#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <cstdio>
#include <string.h>
#include <errno.h>
using namespace std;

//我们将文件描述符fd对应的文件设置为非阻塞
bool SetNoBlock(int fd)
{
    int fl=fcntl(fd,F_GETFL); //获取文件的标志位，这是一个位图
    if(fl<0)
    {
        perror("fcntl error");
        return false;
    }
    fcntl(fd,F_SETFL,fl|O_NONBLOCK); //使用F_SETFL将标志位再设置回去，同时加上一个O_NONBLOCK（非阻塞）参数
    return true;
}

//阻塞IO
int main()
{
    char buffer[1024]; //存放输入的数据缓冲区
    if(SetNoBlock(0)) cout<<"SetNoBlock fd:0 success"<<endl;
    else cout<<"SetNoBlock failed"<<endl;
    sleep(1);
    while(1)
    {
        //cout<<"Please Enter# ";
        //fflush(stdout); //刷新缓冲区

        //ssize_t read(int fd, void *buf, size_t count); 函数返回字节数
        ssize_t n=read(0,buffer,sizeof(buffer)); //文件描述符为标准输入
        if(n>0) //输入成功
        {
            buffer[n-1]='\0';
            cout<<"echo : "<<buffer<<endl;
        }
        else if(n==0)
        {
            cout<<"read done"<<endl;
            break;
        }
        else
        {
            //1.设置为非阻塞轮询，如果底层fd数据没有就绪，recv/read/write/send，返回值会以出错的形式返回
            //2.我们怎么区分真的出错，底层没有就绪
            if(errno==EWOULDBLOCK)
            {
                cout<<"0 fd data not ready,try again!"<<endl;
                sleep(1);
            }
            else
            {
                cerr<<"read error, n="<<n<<" errno code: "<<errno<<" strerror: "<<strerror(errno)<<endl;
            }
            //break;
        }
    }
    return 0;
}